// /////////////////////////////////////////////////////////////////////////////
//
// Name:            SkyDomeComponent.cpp
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Component wrapper of Irrlicht's SceneManager function
//                  addSkyDomeSceneNode(...).
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

// Include files
#include "SkyDomeComponent.h"
#include "../../core/GameManager.h"


// SkyDomeComponent class
// SkyDomeComponent constructor (default)
SkyDomeComponent::SkyDomeComponent(Entity *parent, u32 hRes, u32 vRes, f32 texturePerc,
                                   f32 spherePerc, f32 radius)
: SceneComponent(parent, true)
{
    if(pParent != NULL)
      init(hRes, vRes, texturePerc, spherePerc, radius);
}

// SkyDomeComponent constructor.
SkyDomeComponent::SkyDomeComponent(Entity *parent, const std::string &fileName, u32 hRes, u32 vRes,
                                   f32 texturePerc, f32 spherePerc, f32 radius)
: SceneComponent(parent, true)
{
    if(pParent != NULL)
    {
       init(hRes, vRes, texturePerc, spherePerc, radius);
       setMaterialTexture(0, fileName);
    }
}

// SkyDomeComponent constructor.
SkyDomeComponent::SkyDomeComponent(Entity *parent, ITexture *texture, u32 hRes, u32 vRes,
                                   f32 texturePerc, f32 spherePerc, f32 radius)
: SceneComponent(parent, true)
{
    if(pParent != NULL)
    {
       init(hRes, vRes, texturePerc, spherePerc, radius);
       setMaterialTexture(0, texture);
    }
}

// SkyDomeComponent deconstructor.
SkyDomeComponent::~SkyDomeComponent()
{
}

// Common initialisation method.
void SkyDomeComponent::init(u32 hRes, u32 vRes, f32 texturePerc, f32 spherePerc, f32 radius)
{
    // Create the internal scene node.
    mSceneNode = GameManager::Instance()->getSceneManager()->addSkyDomeSceneNode(0, hRes,
                   vRes, texturePerc, spherePerc, radius, 0, pParent->getID());

    // Set-up internal mechanism for collision detection.
    mTriSelector = NULL;
    mMetaSelector = NULL;
}

// Serializes this object.
bool SkyDomeComponent::onSerialization(SerializedAttributes *attributes)
{
    // Create a root.
    SerializedAttributes *root = new SerializedAttributes();

    // Serialize SceneComponent elements.
    SceneComponent::onSerialization(root);

    // Add root to the given collection of attributes.
    attributes->pushObject("SkyDomeComponent", root);
    root->drop();

    // Return
    return true;
}

// Deserializes this object.
bool SkyDomeComponent::onDeserialization(SerializedAttributes *attributes)
{
    // Retrieve root attribute from the collection.
    SerializedAttribute *rootAttribute = attributes->pullAttribute();

    if(rootAttribute == NULL || rootAttribute->getName() != "SkyDomeComponent")
      return false;

    SerializedAttributes *root = reinterpret_cast<SerializedAttributes*>(rootAttribute->getObject());
    root->grab();

    rootAttribute->drop(); // We no longer need this attribute.

    // Process all attributes in the root collection.
    for(SerializedAttribute *attribute = root->pullAttribute(); attribute != NULL; attribute = root->pullAttribute())
    {
       // Deserialize attributes
       if(attribute->getName() == "SceneComponent")
       {
           // Rewrap attribute so that it can be deserialized properly.
           SerializedAttributes *wrappedAttribute = new SerializedAttributes();
           wrappedAttribute->pushAttribute(attribute);

           // Deserialize the component.
           SceneComponent::onDeserialization(wrappedAttribute);

           // Clean up.
           wrappedAttribute->drop();
       }

       // We no longer need a reference to the attribute.
       attribute->drop();
    }

    // We no longer need a reference to the root.
    root->drop();

    // We're done.
    return true;
}

// End of File
